package com.bosicloud.cmb.ibp.api.manager.service.impl;


import com.bosicloud.cmb.ibp.QueueNames;
import com.bosicloud.cmb.ibp.api.manager.commom.constant.IbpApiStatus;
import com.bosicloud.cmb.ibp.api.manager.commom.constant.ResultConstant;
import com.bosicloud.cmb.ibp.api.manager.commom.constant.StageStatus;
import com.bosicloud.cmb.ibp.api.manager.commom.constant.SubscribeApiStatus;
import com.bosicloud.cmb.ibp.api.manager.commom.model.*;
import com.bosicloud.cmb.ibp.api.manager.commom.vo.*;
import com.bosicloud.cmb.ibp.api.manager.dao.*;
import com.bosicloud.cmb.ibp.api.manager.service.ApimgmtService;
import com.bosicloud.cmb.ibp.api.manager.util.SwaggerParserUtil;
import com.bosicloud.cmb.ibp.aws.adapter.commom.dto.CreateApiParamDTO;
import com.bosicloud.cmb.ibp.commom.dto.Pagination;
import com.bosicloud.cmb.ibp.commom.dto.exchange.ExchangeMessage;
import com.bosicloud.cmb.ibp.commom.exception.BusinessException;
import com.bosicloud.cmb.ibp.commom.utils.DateUtils;
import com.bosicloud.cmb.ibp.commom.utils.JsonUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

import static com.bosicloud.cmb.ibp.commom.dto.exchange.ExchangeAction.*;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.groupingBy;

/**
 * API Manager 服务
 *
 * @author Jack Peng / ziliang.peng@bosicloud.com
 */
@Slf4j
@Service
public class ApimgmtServiceImpl implements ApimgmtService {

    private final IbpApiMapper ibpApiMapper;

    private final IbpApiCategoryMapper ibpApiCategoryMapper;

    private final IbpApiDocsMapper ibpApiDocsMapper;

    private final IbpApiDocParamsMapper ibpApiDocParamsMapper;

    private final IbpApiAwsFailtMsgMapper ibpApiAwsFailtMsgMapper;

    private final QueueMessagingTemplate messagingTemplate;

    private final QueueNames queueNames;

    private final IbpApiStageMapper stageMapper;

    private final IbpUserConsumerApiMapper ibpUserConsumerApiMapper;

    private final IbpApiUsagePlanMapper usagePlanMapper;

    private final IbpApiDocResponseMgsMapper responseMgsMapper;

    private final IbpApiDocResponseHeadersMapper responseHeadersMapper;

    @SuppressWarnings({"SpringJavaAutowiringInspection", "SpringJavaInjectionPointsAutowiringInspection"})
    @Autowired
    public ApimgmtServiceImpl(IbpApiMapper ibpApiMapper, IbpApiCategoryMapper ibpApiCategoryMapper,
                              IbpApiDocsMapper ibpApiDocsMapper,
                              IbpApiDocParamsMapper ibpApiDocParamsMapper,
                              IbpApiAwsFailtMsgMapper ibpApiAwsFailtMsgMapper,
                              QueueMessagingTemplate messagingTemplate,
                              QueueNames queueNames,
                              IbpApiStageMapper ibpApiStageMapper,
                              IbpUserConsumerApiMapper ibpUserConsumerApiMapper,
                              IbpApiUsagePlanMapper usagePlanMapper,
                              IbpApiDocResponseMgsMapper responseMgsMapper,
                              IbpApiDocResponseHeadersMapper responseHeadersMapper) {
        this.ibpApiMapper = ibpApiMapper;
        this.ibpApiCategoryMapper = ibpApiCategoryMapper;
        this.ibpApiDocsMapper = ibpApiDocsMapper;
        this.ibpApiDocParamsMapper = ibpApiDocParamsMapper;
        this.ibpApiAwsFailtMsgMapper = ibpApiAwsFailtMsgMapper;
        this.messagingTemplate = messagingTemplate;
        this.queueNames = queueNames;
        this.stageMapper = ibpApiStageMapper;
        this.ibpUserConsumerApiMapper = ibpUserConsumerApiMapper;
        this.usagePlanMapper = usagePlanMapper;
        this.responseMgsMapper = responseMgsMapper;
        this.responseHeadersMapper = responseHeadersMapper;
    }

    @Override
    public List<IbpApiCategory> allCategory() {
        return ibpApiCategoryMapper.selectAll();
    }

    @Override
    public Pagination<IbpApi> pagingApi(Integer currentPage, Integer pageSize, Optional<Integer> categoryIdOptional) {

        Integer categoryId = categoryIdOptional.orElse(0);

        Pagination<IbpApi> pagination = new Pagination<>(currentPage, pageSize,
                ibpApiMapper.selectByPageCount(categoryId));

        pagination.setPageResult(ibpApiMapper.selectByPage(pagination.getCurrentPageIndex(),
                pageSize, categoryId));

        return pagination;
    }

    @Override
    public Pagination<IbpApiVO> searchApi(Integer currentPage, Integer pageSize, Optional<Integer> categoryIdOptional,
                                          Optional<String> searchTextOptional) {

        Integer categoryId = categoryIdOptional.orElse(0);
        String searchText = searchTextOptional.orElse("");

        Pagination<IbpApiVO> pagination = new Pagination<>(currentPage, pageSize,
                ibpApiMapper.searchApiCount(categoryId, searchText));

        pagination.setPageResult(ibpApiMapper.searchApi(pagination.getCurrentPageIndex(),
                pageSize, categoryId, searchText));

        return pagination;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertIbpApi(IbpApi ibpApi) {
        ibpApi.setStatus(IbpApiStatus.PENDING);
        return ibpApiMapper.insertIbpApi(ibpApi);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertIbpApidocs(IbpApiDocs ibpApiDocs) {
        return ibpApiDocsMapper.insertIbpApiDocs(ibpApiDocs);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertIbpApiDocParams(List<IbpApiDocParams> ibpApiDocParamsList) {
        return ibpApiDocParamsMapper.insertIbpApiDocParams(ibpApiDocParamsList);
    }

    @Override
    public IbpApiVO searchApiDetailById(Integer apiId) {
        return Optional.ofNullable(ibpApiMapper.searchApiDetailById(apiId))
                .map(rs -> {
                    rs.setStageList(getApiStageVOSByApiId(apiId));
                    return rs;
                })
                .orElse(null);
    }

    @Override
    public List<ApiMethodListVO> searchApiMethodListByApiId(Integer apiId) {
        return Optional.ofNullable(ibpApiDocsMapper.searchApiMethodListByApiId(apiId))
                .orElseGet(ArrayList::new);
    }

    @Override
    public IbpApiDocs searchApiDocsInfoById(Integer docsId) {
        return Optional.ofNullable(ibpApiDocsMapper.searchApiDocsInfoById(docsId))
                .orElseGet(IbpApiDocs::new);
    }

    @Override
    public List<IbpApiDocParams> searchParamsListByDocsId(Integer docsId) {
        return Optional.ofNullable(ibpApiDocParamsMapper.searchParamsListByDocsId(docsId))
                .orElseGet(ArrayList::new);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String performAddApiLogic(IbpApi ibpApi) {
        JsonNode jsonNode;
        try {
            jsonNode = JsonLoader.fromURL(new URL(ibpApi.getSwagger()));
        } catch (IOException e) {
            log.error("根据swagger路径读取swagger异常,异常信息:{}", e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
        insertIbpApi(ibpApi);
        SwaggerParserUtil.handleApiPaths(requireNonNull(jsonNode).toString())
                .forEach(ibpApiDocsVO -> performAddApiDocsAndDocsParams(ibpApiDocsVO, ibpApi.getId()));
        // 发送创建api消息
        this.sendMessage(queueNames.getRequest(), CREATE_API,
                CreateApiParamDTO
                        .builder()
                        .apiId(String.valueOf(ibpApi.getId()))
                        .jsonUrl(ibpApi.getSwagger())
                        .failOnWarnings(false)
                        .build());
        return ResultConstant.SUCCESS;
    }

    private void performAddApiDocsAndDocsParams(IbpApiDocsVO ibpApiDocsVO, Integer apiId) {

        ibpApiDocsVO.setApiId(apiId);
        insertIbpApidocs(ibpApiDocsVO);
        Integer apiDocId = ibpApiDocsVO.getId();

        List<IbpApiDocParams> ibpApiDocParamsList = ibpApiDocsVO.getIbpApiDocParamsList()
                .stream()
                .peek(docParams ->
                        {
                            docParams.setApiId(apiId);
                            docParams.setApiDocsId(apiDocId);
                        }
                )
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(ibpApiDocParamsList)) {
            insertIbpApiDocParams(ibpApiDocParamsList);
        }

        List<ResponseMessagesVO> messagesVOList = ibpApiDocsVO.getResponseMessagesVOList();
        if (CollectionUtils.isNotEmpty(messagesVOList)) {
            for (ResponseMessagesVO messagesVO : messagesVOList) {
                IbpApiDocResponseMgs docResponseMgs = IbpApiDocResponseMgs.builder()
                        .apiDocsId(apiDocId)
                        .httpStatusCode(messagesVO.getHttpStatusCode())
                        .reason(messagesVO.getReason())
                        .responseModel(messagesVO.getResponseModel())
                        .createTime(DateUtils.localDateTime2Date())
                        .build();
                responseMgsMapper.insert(docResponseMgs);
                List<ResponseHeaderVO> responseHeaderVOS = messagesVO.getResponseHeaderVOS();
                if (CollectionUtils.isNotEmpty(responseHeaderVOS)) {
                    for (ResponseHeaderVO headerVO : responseHeaderVOS) {
                        responseHeadersMapper.insert(IbpApiDocResponseHeaders.builder()
                                .responseMsgId(docResponseMgs.getId())
                                .name(headerVO.getName())
                                .paramType(headerVO.getParamType())
                                .desp(headerVO.getDesp())
                                .createTime(DateUtils.localDateTime2Date())
                                .build());
                    }
                }
            }
        }

    }

    @Override
    public MethodInfoVO searchApiMethodInfoByDocsId(Integer docsId) {
        MethodInfoVO methodInfoVO = new MethodInfoVO();
        IbpApiDocs ibpApiDocs = searchApiDocsInfoById(docsId);
        BeanUtils.copyProperties(ibpApiDocs, methodInfoVO);
        Map<String, List<IbpApiDocParams>> map = searchParamsListByDocsId(ibpApiDocs.getId())
                .stream()
                .collect(groupingBy(IbpApiDocParams::getParamIn));
        methodInfoVO.setDocParamsMap(map);
        return methodInfoVO;
    }

    @Override
    public List<IbpApiDocs> searchApiDocsListByApiId(Integer apiId) {
        return ibpApiDocsMapper.searchApiDocsListByApiId(apiId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateApiMethodInfo(MethodInfoVO methodInfoVO) {
        IbpApiDocs ibpApiDocs = new IbpApiDocs();
        List<IbpApiDocParams> apiDocParamsList = new ArrayList<>();
        int count = 0;
        if (methodInfoVO.getId() != null && methodInfoVO.getId() > -1) {
            for (Map.Entry<String, List<IbpApiDocParams>> entry : methodInfoVO.getDocParamsMap().entrySet()) {
                apiDocParamsList.addAll(entry.getValue());
            }
            if (!apiDocParamsList.isEmpty()) {
                count = count + ibpApiDocParamsMapper.updateIbpApiDocParams(apiDocParamsList);
            }

            BeanUtils.copyProperties(methodInfoVO, ibpApiDocs);
            count = count + ibpApiDocsMapper.updateByPrimaryKeySelective(ibpApiDocs);

        }
        return count;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer updateIbpApi(IbpApi ibpApi) {
        return ibpApiMapper.updateIbpApi(ibpApi);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertIbpApiAwsFailtMsg(IbpApiAwsFailtMsg apiAwsFailtMsg) {
        return ibpApiAwsFailtMsgMapper.insertIbpApiAwsFailtMsg(apiAwsFailtMsg);
    }

    @Override
    public String deployApi(DeployApiParamVO paramVO) {

        Integer apiId = Integer.parseInt(paramVO.getApiId());
        IbpApiVO ibpApiVO = searchApiDetailById(apiId);
        if (Objects.isNull(ibpApiVO)) {
            throw new BusinessException("非法参数apiId:{},不存在.");
        }
        List<IbpApiUsagePlan> usagePlans = searchUsagePlanListByApiId(apiId);
        if ((CollectionUtils.isNotEmpty(usagePlans) && usagePlans.size() >= 2)
                && ibpApiVO.getIsPublic()) {
            throw new BusinessException("该Api已经部署,请不要重复部署.");
        }
        sendMessage(queueNames.getRequest(), DEPLOY_KEY, paramVO);
        this.updateIbpApiStage(IbpApiStage.builder()
                .apiId(apiId)
                .awsApiId(paramVO.getAwsApiId())
                .endpoint(paramVO.getEndpointUrl())
                .stage(paramVO.getStageName())
                .status(StageStatus.DEPLOYING)
                .build());
        log.info("### 更新Stage状态为:DEPLOYING,apiId:{},stage名称:{}", apiId, paramVO.getStageName());
        return ResultConstant.SUCCESS;
    }

    @Override
    public String getApiNextStatus(Integer apiId) {
        return Optional.ofNullable(searchApiDetailById(apiId))
                .map(IbpApi::getStatus)
                .filter(s -> !IbpApiStatus.FAIL.equalsIgnoreCase(s))
                .map(IbpApiStatus.Utils::nextStatus)
                .orElse(IbpApiStatus.FAIL);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertIbpApiStage(IbpApiStage ibpApiStage) {
        return stageMapper.insertIbpApiStage(ibpApiStage);
    }

    @Override
    public Pagination<IbpApiVO> searchApiDeveloperList(Integer currentPage, Integer pageSize, Integer userId) {
        Pagination<IbpApiVO> pagination = new Pagination<>(currentPage, pageSize, ibpApiMapper.searchApiDeveloperCount(userId));
        List<IbpApiVO> ibpApiVOList = ibpApiMapper.searchApiDeveloperList(pagination.getCurrentPageIndex(), pageSize, userId)
                .stream()
                .peek(rs -> rs.setStageList(getApiStageVOSByApiId(rs.getId())))
                .collect(Collectors.toList());
        pagination.setPageResult(ibpApiVOList);
        return pagination;
    }

    private List<ApiStageVO> getApiStageVOSByApiId(Integer apiId) {

        return stageMapper.searchIbpApiStageList(apiId)
                .stream()
                .map(ibpApiStage -> ApiStageVO.builder()
                        .stage(ibpApiStage.getStage())
                        .status(ibpApiStage.getStatus())
                        .invokeUrl(ibpApiStage.getInvokeUrl())
                        .build())
                .collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String subscribeApi(SubscribeApiParamVO paramVO) {


        final int apiId = Integer.parseInt(paramVO.getApiId());
        final int userId = Integer.parseInt(paramVO.getUserId());
        IbpApiVO ibpApiVO = searchApiDetailById(apiId);
        if (Objects.isNull(ibpApiVO)) {
            throw new BusinessException("非法参数apiId:{},不存在.");
        }

        if (Objects.equals(ibpApiVO.getCreateUser(), userId)) {
            throw new BusinessException("不能订阅自己发布的API.");
        }
        List<IbpApiUsagePlan> usagePlans = searchUsagePlanListByApiId(apiId);
        if (CollectionUtils.isNotEmpty(usagePlans) && usagePlans.size() < 2) {
            throw new BusinessException("当前API还有环境未部署.");
        }
        IbpUserConsumerApi consumerApi = ibpUserConsumerApiMapper.searchIbpUserConsumerApiFor(apiId, userId);
        if (Objects.nonNull(consumerApi)
                && Objects.equals(SubscribeApiStatus.APPLYING, consumerApi.getStatus())) {
            throw new BusinessException("当前API正在订阅中.");
        }
        if (Objects.nonNull(consumerApi)
                && Objects.equals(SubscribeApiStatus.SUCCESS, consumerApi.getStatus())) {
            throw new BusinessException("当前API已经订阅,请不要重复订阅.");
        }
        if (Objects.isNull(consumerApi)) {
            ibpUserConsumerApiMapper.insert(IbpUserConsumerApi.builder()
                    .apiId(apiId)
                    .userId(userId)
                    .createTime(DateUtils.localDateTime2Date())
                    .status(SubscribeApiStatus.APPLYING)
                    .build());
        } else if (Objects.equals(SubscribeApiStatus.FAIL, consumerApi.getStatus())) {
            updateConsumerApi(IbpUserConsumerApi
                    .builder()
                    .apiId(apiId)
                    .userId(userId)
                    .status(SubscribeApiStatus.APPLYING)
                    .build());
        }
        List<IbpUserApiKeyVO> apiKeyVOList = this.searchUserApiKeyListByUserId(userId);
        if (CollectionUtils.isNotEmpty(apiKeyVOList)) {
            for (IbpUserApiKeyVO userApiKey : apiKeyVOList) {
                IbpApiUsagePlan usagePlan = this.searchUsagePlanInfo(apiId, userApiKey.getEnv());
                if (StringUtils.isEmpty(usagePlan.getAwsUsagePlanId())) {
                    continue;
                }
                paramVO.setUsagePlanId(usagePlan.getAwsUsagePlanId());
                paramVO.setKeyId(userApiKey.getAwsKeyId());
                this.sendMessage(queueNames.getRequest(), SUBSCRIBE_KEY, paramVO);
            }
        }
        return ResultConstant.SUCCESS;
    }


    @Override
    public String unSubscribeApi(SubscribeApiParamVO paramVO) {

        final int apiId = Integer.parseInt(paramVO.getApiId());
        final int userId = Integer.parseInt(paramVO.getUserId());
        IbpApiVO ibpApiVO = searchApiDetailById(apiId);
        if (Objects.isNull(ibpApiVO)) {
            throw new BusinessException("非法参数apiId:{},不存在.");
        }
        if (Objects.equals(ibpApiVO.getCreateUser(), userId)) {
            throw new BusinessException("不能取消自己发布的API.");
        }
        IbpUserConsumerApi consumerApi = ibpUserConsumerApiMapper.searchIbpUserConsumerApiFor(apiId, userId);
        if (Objects.nonNull(consumerApi)
                && "N".equalsIgnoreCase(consumerApi.getStatus())) {
            throw new BusinessException("当前API没有订阅.");
        }
        List<IbpUserApiKeyVO> apiKeyVOS = this.searchUserApiKeyListByUserId(userId);
        if (CollectionUtils.isNotEmpty(apiKeyVOS)) {
            for (IbpUserApiKeyVO userApiKeyVO : apiKeyVOS) {
                IbpApiUsagePlan usagePlan = this.searchUsagePlanInfo(apiId, userApiKeyVO.getEnv());
                String usagePlanId = usagePlan.getAwsUsagePlanId();
                if (StringUtils.isEmpty(usagePlanId)) {
                    continue;
                }
                paramVO.setUsagePlanId(usagePlanId);
                paramVO.setKeyId(userApiKeyVO.getAwsKeyId());
                this.sendMessage(queueNames.getRequest(), UN_SUBSCRIBE_KEY, paramVO);
            }
        }
        return ResultConstant.FAILURE;
    }

    @Override
    public String deleteApi(DeleteApiParamVO deleteApiParamVO) {

        IbpApiVO ibpApiVO = searchApiDetailById(Integer.parseInt(deleteApiParamVO.getApiId()));
        if (Objects.isNull(ibpApiVO)) {
            throw new BusinessException("非法参数apiId:{},不存在.");
        }
        if (ibpApiVO.getIsPublic()) {
            throw new BusinessException("已发布的API不能删除.");
        }
        this.sendMessage(queueNames.getRequest(), DELETE_API_KEY, deleteApiParamVO);

        return ResultConstant.SUCCESS;
    }

    @Override
    public Integer insertIbpUserConsumerApi(IbpUserConsumerApi ibpUserConsumerApi) {
        return ibpUserConsumerApiMapper.insertIbpUserConsumerApi(ibpUserConsumerApi);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteIbpApiByApiId(Integer apiId) {
        return ibpApiMapper.deleteIbpApiByApiId(apiId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteIbpApiDocsByApiId(Integer apiId) {
        return ibpApiDocsMapper.deleteIbpApiDocsByApiId(apiId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteIbpApiDocParamsByApiId(Integer apiId) {
        return ibpApiDocParamsMapper.deleteIbpApiDocParamsByApiId(apiId);
    }

    private void sendMessage(String targetQueueName, String action, Object data) {

        log.info("### 发送消息到目标队列,队列名为:{},发送数据为:{}", targetQueueName, JsonUtil.toJson(data));
        messagingTemplate.convertAndSend(targetQueueName,
                ExchangeMessage.builder()
                        .Action(action)
                        .data(data)
                        .build());
        log.info("### 消息发送完毕.");
    }

    @Override
    public Pagination<SubscribeApiListVO> subscribeApiList(Integer currentPage, Integer pageSize, Integer userId) {
        Pagination<SubscribeApiListVO> pagination = new Pagination<>(currentPage, pageSize,
                ibpUserConsumerApiMapper.subscribeApiCount(userId));
        pagination.setPageResult(ibpUserConsumerApiMapper.subscribeApiList(pagination.getCurrentPageIndex(), pageSize, userId));
        return pagination;
    }

    @Override
    public Boolean checkSubscribeIsAvailable(Integer apiId, Integer userId) {

        IbpApiVO ibpApiVO = searchApiDetailById(apiId);
        if (Objects.isNull(ibpApiVO)) {
            return false;
        }
        if (Objects.equals(ibpApiVO.getCreateUser(), userId)) {
            return false;
        }
        if (!ibpApiVO.getIsPublic()) {
            return false;
        }
        IbpUserConsumerApi consumerApi = ibpUserConsumerApiMapper.searchIbpUserConsumerApiFor(apiId, userId);
        if (Objects.isNull(consumerApi)) {
            return true;
        }
        if (Objects.equals(SubscribeApiStatus.APPLYING, consumerApi.getStatus())) {
            return false;
        }
        if (Objects.equals(SubscribeApiStatus.SUCCESS, consumerApi.getStatus())) {
            return false;
        }
        return true;
    }

    @Override
    public IbpApiUsagePlan searchUsagePlanInfo(Integer apiId, String env) {
        return usagePlanMapper.usagePlanList(apiId)
                .stream()
                .filter(us -> Objects.equals(us.getEnv(), env))
                .findAny()
                .orElse(new IbpApiUsagePlan());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer insertIbpApiUsagePlan(IbpApiUsagePlan usagePlan) {
        return usagePlanMapper.insertIbpApiUsagePlan(usagePlan);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteConsumerApi(Integer apiId, Integer userId) {
        return ibpUserConsumerApiMapper.deleteConsumerApi(apiId, userId);
    }

    @Override
    public IbpUserConsumerApi searchIbpUserConsumerApi(Integer apiId, Integer userId) {
        return ibpUserConsumerApiMapper.searchIbpUserConsumerApiFor(apiId, userId);
    }

    @Override
    public Integer updateConsumerApi(IbpUserConsumerApi ibpUserConsumerApi) {
        return ibpUserConsumerApiMapper.updateConsumerApi(ibpUserConsumerApi);
    }

    @Override
    public List<IbpApiUsagePlan> searchUsagePlanListByApiId(Integer apiId) {
        return usagePlanMapper.usagePlanList(apiId);
    }

    @Override
    public IbpApiAwsFailtMsg searchFailMsg(Integer apiId, String bizType, String context) {
        return ibpApiAwsFailtMsgMapper.searchFailMsg(apiId, bizType, context);
    }

    @Override
    public List<IbpUserApiKeyVO> searchUserApiKeyListByUserId(Integer userId) {
        return usagePlanMapper.searchUserApiKeyListByUserId(userId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer updateIbpApiStage(IbpApiStage ibpApiStage) {
        return stageMapper.updateIbpApiStage(ibpApiStage);
    }

    @Override
    public String isPublicApi(Integer apiId) {
        List<IbpApiUsagePlan> usagePlans = searchUsagePlanListByApiId(apiId);
        if (CollectionUtils.isNotEmpty(usagePlans) && usagePlans.size() < 2) {
            throw new BusinessException("该API还有环境未部署完.");
        }

        updateIbpApi(IbpApi
                .builder()
                .id(apiId)
                .isPublic(true)
                .build());
        return ResultConstant.SUCCESS;
    }

    @Override
    public List<IbpApi> searchApiListFor(IbpApi ibpApi) {
        return ibpApiMapper.select(ibpApi);
    }

    @Override
    public List<IbpApiDocResponseMgs> searchApiDocResponseMgsByDocsId(Integer docsId) {
        return responseMgsMapper.select(IbpApiDocResponseMgs.builder()
                .apiDocsId(docsId)
                .build());
    }

    @Override
    public IbpApiDocResponseMgs searchApiDocResponseMgsById(Integer id) {
        return responseMgsMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<IbpApiDocResponseHeaders> searchApiDocResponseHeadersByResponseMsgId(Integer responseMsgId) {
        return responseHeadersMapper.select(IbpApiDocResponseHeaders.builder()
                .responseMsgId(responseMsgId)
                .build());
    }
}
